package tateti;

/**
 *
 * @author Rodrigo
 * Esta clase es la que representa al jugador que tiene que aprender
 * a jugar al ta-te-ti de 5 casillas
 */
public class Jugador {

	private int n = 5;
	private String tipoPieza; // tiene que ser "X" o "O"
	private String tipoPiezaEnemiga; // tiene que ser "X" o "O"	
	private float[] pX; // en pX se guardan los pesos de mis propias piezas
	private float[] pO; // en pO se guardan los pesos de las piezas enemigas
	private float tazaAprendizaje = 0.001f;

	public Jugador(String tipoPieza) {
		this.tipoPieza = tipoPieza;
		if (tipoPieza.equals("X")) {
			this.tipoPiezaEnemiga = "O";
		} else {
			this.tipoPiezaEnemiga = "X";
		}

		// establezco los pesos iniciales de los pX
		pX = new float[n - 1];
		for (int i = 0; i < n - 1; i++) {
			pX[i] = 1.0f;

		}

		// establezco los pesos iniciales de los pO
		pO = new float[n - 1];
		for (int i = 0; i < n - 1; i++) {
			pO[i] = -1.0f;
		}
	}

	public String getTipoPieza(){
		return tipoPieza;
	}

	private float funcOperacional(Tablero t, String pieza, String piezaEnemiga) {
		float suma = 0;
		if (t.getGanador() == null) {
			for (int i = 0; i < n - 1; i++) {
				suma += pX[i] * (float) t.cantLineasLargoL(pieza, i + 1);
				suma += pO[i] * (float) t.cantLineasLargoL(piezaEnemiga, i + 1);
			}
			if (suma < -90.0f) {
				return -90.0f;
			}
			if (suma > 90.0f) {
				return 90.0f;
			}
			return suma;
		} else {
			if (t.getGanador().equals(pieza)) {
				return 100.0f;
			} else if (t.getGanador().equals("Empate")) {
				return 0.0f;
			} else {
				return -100.0f;
			}
		}


	}

	public void elegirJugada(Tablero t, int[] iJugada, int[] jJugada) {
		iJugada[0] = 0;
		jJugada[0] = 0;
		float maxFuncJugada = 0;
		boolean primeraVez = true;
		if (t.getGanador() == null) {
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					if (t.getElem(i, j).equals("")) {
						t.setElem(i, j, tipoPieza);
						float funcaux;
						if (t.getGanador() == null) {
							int[] iRival = new int[1];
							int[] jRival = new int[1];
							simularJugadaRival(new Tablero(t), iRival, jRival);
							t.setElem(iRival[0], jRival[0], tipoPiezaEnemiga);
							funcaux = funcOperacional(t, tipoPieza, tipoPiezaEnemiga);
							t.setElem(iRival[0], jRival[0], "");
						} else {
							funcaux = funcOperacional(t, tipoPieza, tipoPiezaEnemiga);
						}
						if (funcaux >= maxFuncJugada || primeraVez) {
							iJugada[0] = i;
							jJugada[0] = j;
							maxFuncJugada = funcaux;
							primeraVez = false;
						}
						t.setElem(i, j, "");
					}
				}
			}
		} else {
			maxFuncJugada = funcOperacional(t, tipoPieza, tipoPiezaEnemiga);
		}
		aprender(maxFuncJugada, t);
	}

	private void simularJugadaRival(Tablero t, int[] iJugada, int[] jJugada) {
		iJugada[0] = 0;
		jJugada[0] = 0;
		float maxFuncJugada = 0;
		boolean primeraVez = true;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (t.getElem(i, j).equals("")) {
					t.setElem(i, j, tipoPiezaEnemiga);
					float funcaux = funcOperacional(t, tipoPiezaEnemiga, tipoPieza);
					if (funcaux >= maxFuncJugada || primeraVez) {
						iJugada[0] = i;
						jJugada[0] = j;
						maxFuncJugada = funcaux;
						primeraVez = false;
					}
					t.setElem(i, j, "");
				}
			}
		}

	}

	private void aprender(float funcEntrenamiento, Tablero t) {
		float funcOper = funcOperacional(t, tipoPieza, tipoPiezaEnemiga);
		//System.out.println("::::::::::>>>>>" + (funcEntrenamiento - funcOper));
		for (int pesos = 0; pesos < n - 1; pesos++) {
			pX[pesos] = pX[pesos] + tazaAprendizaje * (funcEntrenamiento - funcOper) * t.cantLineasLargoL(tipoPieza, pesos + 1);
			pO[pesos] = pO[pesos] - tazaAprendizaje * (funcEntrenamiento - funcOper) * t.cantLineasLargoL(tipoPiezaEnemiga, pesos + 1);
		}
	}
}
